//
// Created by 11518 on 2024/11/25.
//

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <thread>
#include "../log.h"
#include "tcpserver.h"

void Tcpserver::acceptClient(){
    while (m_IsOpen){
        if(!m_Connect){
            m_SocketClient = accept(m_SocketFd, NULL, NULL);
            if(m_SocketClient < 0){
                LOGD("error accept:%d",m_SocketClient);
                close(m_SocketFd);
//            return 3;
            }
            m_Connect = true;
        }else{
            char buff[1024];
            memset(buff,0,sizeof(buff));
            int ret = read(m_SocketClient,buff,1024);
            if(ret < 0){
                LOGD("ret:%d",ret);
                m_IsOpen = false;
            }else if(ret==0){
                LOGD("ret:%d",ret);
                m_Connect = false;
            }else{
                LOGD("ret:%d %s",ret,buff);
            }
        }
        usleep(500 * 1000);
    }
}

int Tcpserver::init(const char *ip, int port) {
    m_Connect = false;
    m_SocketFd = socket(AF_INET, SOCK_STREAM, 0);
    if(m_SocketFd < 0){
        perror("socket");
        return 1;
    }
    LOGD("socket create success..................\n");

    //2.绑定本机地址和端口
    struct sockaddr_in address{};
    memset(&address, 0, sizeof(address));
    address.sin_family = AF_INET;
    address.sin_port	  = htons(port);//端口号
    address.sin_addr.s_addr = inet_addr(ip);//本机IP地址
    int ret = bind(m_SocketFd, (struct sockaddr*)&address, sizeof(address));
    if(ret < 0){
        LOGD("error bind:%d",ret);
        close(m_SocketFd);
        return 2;
    }

    //3.设置监听套接字
    ret = listen(m_SocketFd,10);
    if(ret < 0){
        LOGD("error listen:%d",ret);
        close(m_SocketFd);
        return 3;
    }
    LOGD("listen...............\n");

    m_IsOpen = true;
    std::thread ad(&Tcpserver::acceptClient,this);
    ad.detach();
    return 0;
}

void Tcpserver::unInit() {
    m_IsOpen = false;

    close(m_SocketFd);
}

int Tcpserver::writeData(const char *str, int size) {
    if(m_Connect){
        return write(m_SocketClient,str,size);
    }
    return -1;
}
